//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <bsp.h>
#include "mc146818.h"

INLINE uint8_t BCDToBinary(uint8_t u8BCD)
{
    return (u8BCD >> 4) * 10 + (u8BCD & 0xf);
}

INLINE uint8_t BinaryToBCD(uint8_t u8Binary)
{
    return ((u8Binary / 10) << 4) + (u8Binary % 10);
}

// NOTE: Maybe need disable interrupt
EXTERN_C void CDECL BspGetRTCTime(RTCTime *pRTCTime)
{
    assert(pRTCTime);

    while (ReadRTC(RTCRegister_StatusA) & SRA_UIP);

    pRTCTime->uSeconds  = BCDToBinary(ReadRTC(RTCRegister_CurrenSecond));
    pRTCTime->uMinutes  = BCDToBinary(ReadRTC(RTCRegister_CurrentMinute));
    pRTCTime->uHours    = BCDToBinary(ReadRTC(RTCRegister_CurrentHour));
    pRTCTime->uDate     = BCDToBinary(ReadRTC(RTCRegister_CurrentDateOfMonth));
    pRTCTime->uMonth    = BCDToBinary(ReadRTC(RTCRegister_CurrentMonth));
    pRTCTime->uYear     = BCDToBinary(ReadRTC(RTCRegister_CurrentYear));

    // alternate arithmetic:
    // pRTCTime->uYear += 1900;
    // if (1970 > pRTCTime->uYear) pRTCTime->uYear += 100;
    pRTCTime->uYear     += 100 * BCDToBinary(ReadRTC(RTCRegister_Century));
}

// NOTE: Maybe need disable interrupt
EXTERN_C void CDECL BspSetRTCTime(const RTCTime *pRTCTime)
{
    while (ReadRTC(RTCRegister_StatusA) & SRA_UIP);

    WriteRTC(RTCRegister_StatusB, SRB_SET | SRB_24H);

    WriteRTC(RTCRegister_CurrenSecond, BinaryToBCD(pRTCTime->uSeconds));
    WriteRTC(RTCRegister_CurrentMinute, BinaryToBCD(pRTCTime->uMinutes));
    WriteRTC(RTCRegister_CurrentHour, BinaryToBCD(pRTCTime->uHours));
    WriteRTC(RTCRegister_CurrentDateOfMonth, BinaryToBCD(pRTCTime->uDate));
    WriteRTC(RTCRegister_CurrentMonth, BinaryToBCD(pRTCTime->uMonth));
    WriteRTC(RTCRegister_CurrentYear, BinaryToBCD(pRTCTime->uYear % 100));
    WriteRTC(RTCRegister_Century, BinaryToBCD(pRTCTime->uYear / 100));

    WriteRTC(RTCRegister_StatusB, SRB_PIE | SRB_24H);
}
